home *** CD-ROM | disk | FTP | other *** search
- /*
- * util.c -- general utility functions.
- */
-
- #include <ctype.h>
- #include "../h/config.h"
- #include "general.h"
- #include "tproto.h"
- #include "../h/cpuconf.h"
- #include "globals.h"
- #include "trans.h"
- #include "tree.h"
-
-
- extern int optind;
-
- extern char *ofile;
-
- /*
- * The following code is operating-system dependent [@util.01]. Define the
- * characters that terminate a file name prefix.
- */
-
- #if PORT
- #define Prefix "/"
- Deliberate Syntax Error
- #endif /* PORT */
-
- #if ARM
- #define Prefix ".:"
- #endif /* ARM */
-
- #if AMIGA
- #define Prefix "/:"
- #endif /* AMIGA */
-
- #if ATARI_ST
- #define Prefix "/:\\"
- #endif /* ATARI_ST */
-
- #if HIGHC_386 || MSDOS || OS2
- #define Prefix "/:\\"
- #endif /* HIGHC_386 || MSDOS || OS2 */
-
- #if MACINTOSH
- #define Prefix ":"
- #endif /* MACINTOSH */
-
- #if MVS || VM
- #define Prefix ""
- #endif /* MVS || VM */
-
- #if UNIX
- #define Prefix "/"
- #endif /* UNIX */
-
- #if VMS
- #define Prefix "]:"
- #endif /* VMS */
-
- /*
- * End of operating-system specific code.
- */
-
- /*
- * Information about Icon functions.
- */
-
- /*
- * Number of arguments.
- */
-
-
- /*
- * Names of Icon functions.
- */
- char *ftable[] = {
- #define FncDef(p,n) Lit(p),
- #define FncDefV(p) Lit(p),
- #include "../h/fdefs.h"
- #undef FncDef
- #undef FncDefV
- };
-
- int ftbsize = sizeof(ftable)/sizeof(char *);
-
- /*
- * alloc - allocate n bytes
- */
-
- pointer alloc(n)
- unsigned int n;
- {
- pointer a;
-
- if (!(a = malloc((msize)n)))
- quit("out of memory");
- return a;
- }
-
- /*
- * salloc - allocate and initialize string
- */
-
- char *salloc(s)
- char *s;
- {
-
- return strcpy((char *)alloc((unsigned int)(strlen(s)+1)),s);
- }
-
- /*
- * tcalloc - allocate and zero m*n bytes
- */
- pointer tcalloc(m,n)
- unsigned int m, n;
- {
- pointer a;
-
- if (!(a = calloc(m,n)))
- quit("out of memory");
- return a;
- }
-
- /*
- * fparse - break a file name down into component parts.
- * Result is a pointer to a struct of static pointers good until the next call.
- */
- struct fileparts *fparse(s)
- char *s;
- {
- #if ARM
- static char buf[MaxFileName+2];
- static struct fileparts fp;
- char *p;
- char *ext = 0;
- char *extend = 0;
- char *dirend = 0;
- char *s1;
- char *bp = buf;
-
- /* First, skip any filing system prefix */
- s1 = index(s,':');
- if (s1 == NULL)
- s1 = s;
- else
- ++s1;
-
- /* Now, scan backwards through the filename, looking for dots.
- * Record the positions of the final two, for later use.
- */
- p = s1 + strlen(s1);
- fp.name = 0;
-
- while (--p > s1)
- {
- if (*p != '.')
- continue;
-
- if (fp.name == NULL)
- {
- fp.name = p + 1;
- extend = p;
- }
- else
- {
- ext = p + 1;
- dirend = p;
- break;
- }
- }
-
- /* This is the simple case. The filename is a simple name, with no
- * directory part. The extension is therefore null, and the directory
- * is just the filing system prefix, if any.
- */
- if (fp.name == NULL)
- {
- fp.name = s1;
-
- if (s1 == s)
- {
- fp.ext = "";
- fp.dir = "";
- }
- else
- {
- fp.ext = "";
- strncpy(buf, s, s1 - s);
- buf[s1-s] = '\0';
- fp.dir = buf;
- }
-
- return &fp;
- }
-
- /* Now worry about the more complicated cases. First, check the
- * supposed extension, to see if it is one of the valid cases,
- * SourceSuffix, U1Suffix, U2Suffix, or USuffix. For this code
- * to work, these four defined values must start with a dot, and
- * be all in lower case.
- */
- *buf = '.';
- bp = buf + 1;
-
- for (p = ext ? ext : s1; p < extend; ++p)
- {
- *bp++ = tolower(*p);
- }
-
- *bp++ = '\0';
-
- if (strcmp(buf,SourceSuffix) == 0 || strcmp(buf,U1Suffix) == 0
- || strcmp(buf,U2Suffix) == 0 || strcmp(buf,USuffix) == 0)
- {
- fp.ext = buf;
- }
- else
- {
- fp.ext = "";
- bp = buf;
- dirend = extend;
- }
-
- /* We now have the name and extension sorted out. So we just need
- * to copy the directory part into buf (at bp), and set fp.dir.
- */
- if (dirend == NULL)
- {
- if (s1 == s)
- fp.dir = "";
- else
- {
- fp.dir = bp;
-
- while (s < s1)
- *bp++ = *s++;
-
- *bp = '\0';
- }
- }
- else
- {
- fp.dir = bp;
-
- while (s <= dirend)
- *bp++ = *s++;
-
- *bp = '\0';
- }
-
- return &fp;
-
- #else /* ARM */
-
- static char buf[MaxFileName+2];
- static struct fileparts fp;
- int n;
- char *p, *q;
- char *index();
-
- #if MVS /* for any compiler which takes member names */
- static char extbuf [MaxFileName+2] ;
-
- p = index(s, '(');
- if (p) {
- fp.member = p+1;
- memcpy(extbuf, s, p-s);
- extbuf [p-s] = '\0';
- s = extbuf;
- }
- else fp.member = s + strlen(s);
- #endif /* MVS */
-
- q = s;
- fp.ext = p = s + strlen(s);
- while (--p >= s) {
- if (*p == '.' && *fp.ext == '\0')
- fp.ext = p;
- else if (index(Prefix,*p)) {
- q = p+1;
- break;
- }
- }
- fp.dir = buf;
- n = q - s;
- strncpy(fp.dir,s,n);
- fp.dir[n] = '\0';
- fp.name = buf + n + 1;
- n = fp.ext - q;
- strncpy(fp.name,q,n);
- fp.name[n] = '\0';
- return &fp;
-
- #endif /* not ARM */
- }
-
- /*
- * makename - make a file name, optionally substituting a new dir and/or ext
- */
- char *makename(dest,d,name,e)
- char *dest, *d, *name, *e;
- {
- struct fileparts fp;
- fp = *fparse(name);
- if (d != NULL)
- fp.dir = d;
- if (e != NULL)
- fp.ext = e;
-
- #if ARM
-
- {
- char *p = (*fp.ext ? fp.ext + 1 : "");
- sprintf(dest, "%s%s%s%s", fp.dir, p, (*p ? "." : ""), fp.name);
- }
-
- #else /* ARM */
-
- #if MVS
- if (*fp.member)
- sprintf(dest,"%s%s%s(%s", fp.dir, fp.name, fp.ext, fp.member);
- else
- #endif /* MVS */
-
- sprintf(dest,"%s%s%s",fp.dir,fp.name,fp.ext);
-
- #endif /* ARM */
-
- return dest;
- }
-
- /*
- * quit - immediate exit with error message
- */
-
- novalue quit(msg)
- char *msg;
- {
- quitf(msg,"");
- }
-
- /*
- * quitf - immediate exit with message format and argument
- */
- novalue quitf(msg,arg)
- char *msg, *arg;
- {
-
-
- extern char *progname;
- fprintf(stderr,"%s: ",progname);
- fprintf(stderr,msg,arg);
- fprintf(stderr,"\n");
-
- #ifndef VarTran
- if (ofile)
- unlink(ofile); /* remove bad icode file */
- #endif /* VarTran */
-
- exit(ErrorExit);
- }
-
- /*
- * tsyserr is called for fatal errors. The message s is produced and the
- * translator exits.
- */
- novalue tsyserr(s)
- char *s;
- {
-
-
- if (tok_loc.n_file)
- fprintf(stderr, "File %s; ", tok_loc.n_file);
- fprintf(stderr, "Line %d # %s\n", in_line, s);
-
- exit(ErrorExit);
- }
-
-
- /*
- * round2 - round an integer up to the next power of 2.
- */
- unsigned int round2(n)
- unsigned int n;
- {
- unsigned int b = 1;
- while (b < n)
- b <<= 1;
- return b;
- }
-
-
- /*
- * sizearg - process -S command option.
- */
-
- struct keyptr { /* structure for listing option chars */
- char *cmd; /* option character(s) */
- unsigned int *valp; /* pointer to value word */
- };
-
- static struct keyptr keytable[] = { /* maps keys to store addresses */
-
- #define Size(cmd,vname,defalt) cmd, &vname,
- #define MinSize(x,y,z)
- #include "sizes.h" /* initialize from "sizes.h" data */
- #undef Size
- #undef MinSize
- 0, 0, /* terminate with null entry */
- };
-
- novalue sizearg(arg,argv)
- char *arg;
- char **argv;
- {
- struct keyptr *k; /* key table pointer */
- char *s; /* value string pointer */
- int v; /* option value */
-
- for (k = keytable; k->cmd; k++) /* search for key match */
- if (arg[0] == k->cmd[0] && (arg[0] != 'h' || arg[1] == k->cmd[1]))
- break;
-
- if (k->cmd == NULL) /* abort if not found */
- quitf("unrecognized -S option: -S%s",arg);
-
- if (arg[0] == 'h')
- s = &arg[2]; /* find value */
- else
- s = &arg[1];
-
- if (*s == '\0') { /* if value is in next arg */
- s = argv[optind++];
- if (s == NULL)
- quitf("missing value: -S%s", arg);
- }
-
- v = (int)atol(s); /* convert integer -- check */
- if (v <= 0)
- quitf("illegal value: -S%s", arg);
- *k->valp = v; /* store result */
- }
-
-
- /*
- * smatch - case-insensitive string match - returns nonzero if they match
- */
- int smatch(s,t)
- char *s, *t;
- {
- char a, b;
- for (;;) {
- while (*s == *t)
- if (*s++ == '\0')
- return 1;
- else
- t++;
- a = *s++;
- b = *t++;
- if (isupper(a)) a = tolower(a);
- if (isupper(b)) b = tolower(b);
- if (a != b)
- return 0;
- }
- }
-